package com.tanhua.manage.service;

import cn.hutool.core.date.DateUtil;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.TitleAndAmount;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.sso.pojo.LoginInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class DashboardService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private MongoTemplate mongoTemplate;

    public Map getActiveInfo() {
        Map<String, Integer> activeInfo = new HashMap();
        Long today = getTime(0);
        Long yesterday = getTime(-1);

        try {
            //累计用户
            QueryWrapper<User> activeQuery = new QueryWrapper<>();
            Integer cumulativeUsers = this.userMapper.selectCount(activeQuery);
            activeInfo.put("cumulativeUsers", cumulativeUsers);

            //过去30天活跃用户
            Long OneMonthAgo = getTime(-30);
            Integer activePassMonth = getActiceUser(OneMonthAgo, today, LoginInfo.class);
            activeInfo.put("activePassMonth", activePassMonth);

            //过去7天活跃用户
            Long OneWeekAgo = getTime(-7);
            Integer activePassWeek = getActiceUser(OneWeekAgo, today, LoginInfo.class);
            activeInfo.put("activePassWeek", activePassWeek);

            //今日新增用户
            Integer newUsersToday = getNewUser(today, LoginInfo.class);
            activeInfo.put("newUsersToday", newUsersToday);

            //今日新增用户涨跌率，单位百分数，正数为涨，负数为跌
            Integer newUsersYesterday = getNewUser(yesterday, today, LoginInfo.class);
            Integer newUsersTodayRate = getRate(newUsersToday, newUsersYesterday);
            activeInfo.put("newUsersTodayRate", newUsersTodayRate);

            //今日登录次数
            Query loginTimesTodayQuery = Query.query(Criteria.where("loginTime").gt(today));
            Integer loginTimesToday = mongoTemplate.find(loginTimesTodayQuery, LoginInfo.class).size();
            activeInfo.put("loginTimesToday", loginTimesToday);

            //今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
            Query loginTimesYesterdayQuery = Query.query(Criteria.where("loginTime").gt(yesterday).lt(today));
            Integer loginTimesYesterday = mongoTemplate.find(loginTimesYesterdayQuery, LoginInfo.class).size();
            Integer loginTimesTodayRate = getRate(loginTimesToday, loginTimesYesterday);
            activeInfo.put("loginTimesTodayRate", loginTimesTodayRate);

            //过去7天平均日使用时长，单位秒
            activeInfo.put("useTimePassWeek", 60 * 60 * 8);

            //今日活跃用户
            Integer activeUsersToday = getActiceUser(today, LoginInfo.class);
            activeInfo.put("activeUsersToday", activeUsersToday);

            //昨日活跃用户
            Integer activeUsersYesterday = getActiceUser(yesterday,today, LoginInfo.class);
            activeInfo.put("activeUsersYesterday", activeUsersYesterday);

            //今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
            Integer activeUsersTodayRate = getRate(activeUsersToday, activeUsersYesterday);
            activeInfo.put("activeUsersTodayRate", activeUsersTodayRate);

            //昨日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
            Long theDayBeforeYesterday = getTime(-2);
            Integer activeUsersTheDayBeforeYesterday = getActiceUser(theDayBeforeYesterday,yesterday, LoginInfo.class);
            Integer activeUsersYesterdayRate = getRate(activeUsersYesterday, activeUsersTheDayBeforeYesterday);
            activeInfo.put("activeUsersYesterdayRate",activeUsersYesterdayRate);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return activeInfo;
    }

    //获取日期时间戳
    public Long getTime(Integer numberOfDays) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());
        calendar.add(calendar.DATE, numberOfDays);
        String day = sdf.format(calendar.getTime());
        String dayTime = day + " 00:00:00";
        Date date = null;
        try {
            date = sdf2.parse(dayTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date.getTime();
    }

    //获取百分比
    public Integer getRate(Integer today, Integer yesterday) {
        if (yesterday == 0){
            return 0;
        }
        DecimalFormat decimalFormat = new DecimalFormat(".00");
        String rateStr = decimalFormat.format((float) today / yesterday * 100);
        Integer rate = Math.toIntExact(Math.round(Double.valueOf(rateStr))) - 100;
        return rate;
    }


    public Map<String,List<TitleAndAmount>> getNewUsersInfo(Long sd, Long ed, Date sdTime, Date edTime, Date edMonthAfterTime, Integer type) {

        Map<String,List<TitleAndAmount>> usersInfo = new HashMap();
        List<TitleAndAmount> lastYaer = new ArrayList<>();
        List<TitleAndAmount> thisYaer = new ArrayList<>();

        //定义日期实例
        Calendar calendar = Calendar.getInstance();

        //设置日期起始时间
        calendar.setTime(sdTime);

        //获取目前的年份
        int nowYear = DateUtil.year(new Date());

        //如果起始月份跟结束月份是在一个月
        if (sdTime.getTime() == edTime.getTime()){
            TitleAndAmount titleAndAmount = new TitleAndAmount();
            //获取当前月份
            Integer thisMonth = DateUtil.month(new Date(sd));
            thisMonth = thisMonth == 12 ? 1 : thisMonth+1;
            titleAndAmount.setTitle(thisMonth.toString());

            if (101 == type){
                //新增用户
                Integer newCount = getNewUser(sd, ed, LoginInfo.class);
                titleAndAmount.setAmount(newCount);
            }else if(102 == type){
                //活跃用户
                Integer acticeUser = getActiceUser(sd, ed, LoginInfo.class);
                titleAndAmount.setAmount(acticeUser);
            }else if (103 == type){
                //次日留存用户
                titleAndAmount.setAmount(0);
            }

            //获取当前年份
            int year = DateUtil.year(new Date(sd));

            //根据年份存入年份集合
            if (year == nowYear){
                thisYaer.add(titleAndAmount);
            }else if (year == nowYear - 1){
                lastYaer.add(titleAndAmount);
            }
        }else {

            //若不是在一个月内,进行while循环判断是否到结束日期
            while (calendar.getTime().before(edMonthAfterTime)) {
                //获取当前月份的第一天
                Date thisMonthFirstDayDate = calendar.getTime();
                Long thisMonthFirstDay = thisMonthFirstDayDate.getTime();

                TitleAndAmount titleAndAmount = new TitleAndAmount();
                //获取当前月份
                Integer thisMonth = DateUtil.month(thisMonthFirstDayDate);
                thisMonth = thisMonth == 12 ? 1 : thisMonth + 1;
                titleAndAmount.setTitle(thisMonth.toString());

                //获取当前月份的最后一天
                calendar.add(Calendar.MONTH, 1);//进行当前日期月份加1
                calendar.add(Calendar.DAY_OF_MONTH, -1);//日期倒数一日,即得本月最后一天
                Long thisMonthLastDay = calendar.getTime().getTime();

                if (101 == type) {
                    //新增用户
                    Integer activeCount = getNewUser(thisMonthFirstDay, thisMonthLastDay, LoginInfo.class);
                    titleAndAmount.setAmount(activeCount);
                } else if (102 == type) {
                    //活跃用户
                    Integer acticeUser = getActiceUser(thisMonthFirstDay, thisMonthLastDay, LoginInfo.class);
                    titleAndAmount.setAmount(acticeUser);
                } else if (103 == type) {
                    //次日留存用户
                    titleAndAmount.setAmount(0);
                }

                //获取查询的年份
                int year = DateUtil.year(thisMonthFirstDayDate);

                //根据年份存入年份集合
                if (year == nowYear) {
                    thisYaer.add(titleAndAmount);
                } else if (year == nowYear - 1) {
                    lastYaer.add(titleAndAmount);
                }

                calendar.add(Calendar.DAY_OF_MONTH, 1);//加回一天,表示下个月

            }
        }
        usersInfo.put("thisYaer",thisYaer);
        usersInfo.put("lastYaer",lastYaer);
        return usersInfo;
    }

    //获取新增用户
    public<T> Integer getNewUser(Long gtDate, Long ltDate, Class<T> resultClass  ){
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("isNew").is(true),
                Criteria.where("createdTime").gt(gtDate).lt(ltDate));
        Query query = Query.query(criteria);
        Integer newUser = mongoTemplate.find(query, resultClass).size();
        return newUser;
    }

    //重载获取新增用户
    public<T> Integer getNewUser(Long gtDate, Class<T> resultClass  ){
        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("isNew").is(true),
                Criteria.where("createdTime").gt(gtDate));
        Query query = Query.query(criteria);
        Integer newUser = mongoTemplate.find(query, resultClass).size();
        return newUser;
    }

    //获取活跃用户
    public<T> Integer getActiceUser(Long gtDate, Long ltDate, Class<T> resultClass){
        Query query = Query.query(Criteria.where("loginTime").gt(gtDate).lt(ltDate));
        Integer activeUser = mongoTemplate.findDistinct(query,"userId",resultClass, resultClass).size();
        return activeUser;
    }

    //重载获取活跃用户
    public<T> Integer getActiceUser(Long gtDate, Class<T> resultClass  ){
        Query query = Query.query(Criteria.where("loginTime").gt(gtDate));
        Integer activeUser = mongoTemplate.findDistinct(query,"userId",resultClass, resultClass).size();
        return activeUser;
    }


    //获取地区分布信息
    public Map getDistributionInfo(Long sd, Long ed, Date sdTime, Date edTime, Date edMonthAfterTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date sdDate = new Date(sd);
        Date edDate = new Date(ed);

        Map<String,List<TitleAndAmount>> distributionInfo = new HashMap();

        //industryDistribution,行业分布TOP10
//        List<TitleAndAmount> industryDistribution = this.userInfoMapper.selectIndustry(sdDate,edDate);
        List<TitleAndAmount> industryDistribution = this.userInfoMapper.selectIndustry();
        distributionInfo.put("industryDistribution",industryDistribution);

        //ageDistribution,年龄分布
        List<TitleAndAmount> ageDistribution = this.userInfoMapper.selectAge();
        distributionInfo.put("ageDistribution",ageDistribution);

        //genderDistribution,性别分布
//        List<TitleAndAmount> genderDistribution = this.userInfoMapper.selectSex(sdDate,edDate);
        List<TitleAndAmount> genderDistribution = this.userInfoMapper.selectSex();
        distributionInfo.put("genderDistribution",genderDistribution);

        //localDistribution,地区分布
        List<TitleAndAmount> localDistribution = this.userInfoMapper.selectCity();
        distributionInfo.put("localDistribution",localDistribution);

        //localTotal,地区合计


        return distributionInfo;
    }
}
